
// ************************************
// * GStore - Inventory System - thomasfn *
// ************************************
// CLIENTSIDE

------------------------------------------------------------------------------------------------
-- DSlot
------------------------------------------------------------------------------------------------

	local DSlot = {}

	local colBG = Color( 128, 128, 128, 255 )
	local colSelBG = Color( 170, 170, 170, 255 )
	local colHovBG = Color( 150, 150, 150, 255 )
	local camPos = Vector( 50, 50, 50 )
	local camAng = (Vector( 50, 50, 10 )*-1):Angle()

	AccessorFuncCB( DSlot, "m_tItem", "Item", nil, function( pn, _, val )
		local mdl = pn.Model
		if (val) then
			// print( "[GStore_UI] Slot " .. tostring( pn ) .. " has been assigned (" .. tostring( val ) .. ")" )
			mdl:SetVisible( true )
			gstore_ui.SetupIcon( mdl, val, 60 )
		else
			mdl:SetVisible( false )
		end
	end )

	local vecOrig = Vector( 0, 0, 0 )
	local angOrig = Angle( 0, 0, 0 )
	function DSlot:Init()
		local mdl = vgui.Create( "DModelPanel", self )
		mdl:MouseCapture( false )
		mdl:SetVisible( false )
		function mdl.DoClick() self:DoClick() end -- I used .  on purpose here
		self.Model = mdl
	end
	function DSlot:DoClick()
	
	end
	function DSlot:PerformLayout()
		local mdl = self.Model
		mdl:SetPos( 5, 5 )
		mdl:SetSize( self:GetWide()-10, self:GetTall()-10 )
	end
	
	function DSlot:Paint()
		local w, h = self:GetSize()
		local col = colBG
		if (self.Selected) then col = colSelBG end
		if (self.Hovered) then col = colHovBG end
		surface.SetDrawColor( col )
		surface.DrawRect( 0, 0, w, h )
		surface.SetDrawColor( 0, 0, 0, 128 )
		surface.DrawLine( 0, 0, w, 0 )
		surface.DrawLine( 0, 1, 0, h-1 )
		surface.SetDrawColor( 255, 255, 255, 128 )
		surface.DrawLine( w-1, 1, w-1, h )
		surface.DrawLine( 0, h-1, w-1, h-1 )
		/*local item = self:GetItem()
		if (item && ValidEntity( item.Entity )) then
			local ent = item.Entity
			local oldpos, oldang = ent:GetPos(), ent:GetAngles()
			local x, y = self:LocalToScreen( 5, 5 )
			ent:SetPos( vecOrig )
			ent:SetAngles( angOrig )
			ent:SetNoDraw( false )
			
				cam.Start3D( camPos, camAng, 70, x, y, w-10, h-10 )
				cam.IgnoreZ( true )
				render.SuppressEngineLighting( true )
				render.SetLightingOrigin( vecOrig )
				render.ResetModelLighting( 0.2, 0.2, 0.2 )
				render.SetColorModulation( 1, 1, 1 )
				render.SetBlend( 1 )
				render.SetModelLighting( BOX_TOP, 1, 1, 1 )
				render.SetModelLighting( BOX_FRONT, 1, 1, 1 )
				
				ent:DrawModel()
				
				render.SuppressEngineLighting( false )
				cam.IgnoreZ( false )
				cam.End3D()
			
			ent:SetPos( oldpos )
			ent:SetAngles( oldang )
			ent:SetNoDraw( not ent.InWorld )
		end*/
	end
	
	vgui.Register( "DSlot", DSlot, "Panel" )
------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------------------
-- DSlotPanel
------------------------------------------------------------------------------------------------

	local DSlotPanel = {}

	local SlotSize = 46
	local SlotPadding = 4
	function DSlotPanel:Setup( slotcnt )
		local slots = {}
		self.Slots = slots
		local i
		for i=1, slotcnt do
			local sl = vgui.Create( "DSlot", self )
			slots[ i ] = sl
		end
		self:InvalidateLayout()
	end
	function DSlotPanel:PerformLayout()
		local slots_in_row = math.floor( (self:GetWide() - SlotPadding) / (SlotSize + SlotPadding) )
		local rows = math.floor( (self:GetTall() - SlotPadding) / (SlotSize + SlotPadding) )
		local x, y, i = 0, 0, 0
		for y=1, rows do
			for x=1, slots_in_row do
				i = i + 1
				local sl = self.Slots[ i ]
				if (!ValidPanel( sl )) then return end
				sl:SetPos( SlotPadding + (SlotSize+SlotPadding)*(x-1), SlotPadding + (SlotSize+SlotPadding)*(y-1) )
				sl:SetSize( SlotSize, SlotSize )
			end
		end
	end
	vgui.Register( "DSlotPanel", DSlotPanel, "Panel" )
	
------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------------------
-- DInventory
------------------------------------------------------------------------------------------------
	
	local DInventory = {}
	
	local InventoryList = {}
	
	function UpdateInventories( inv )
		for _, pn in pairs( InventoryList ) do
			if (ValidPanel( pn )) then
				pn:Update( inv )
				pn:InvalidateLayout( true )
			end
		end
	end
	
	local slotSize = 40
	function DInventory:Setup( inv )
		self.LastInv = inv
		local pnAction = vgui.Create( "DPanelList", self )
		function pnAction:Paint()
		
		end
		pnAction:EnableHorizontal( false )
		pnAction:EnableVerticalScrollbar( false )
		pnAction:SetPadding( 0 )
		pnAction:SetSpacing( 4 )
		self.ActionPanel = pnAction
		
		local pnInfo = vgui.Create( "DPanel", self )
		self.InfoPanel = pnInfo
		
		self:Update( inv )
		table.insert( InventoryList, self )
	end
	
	function DInventory:Update( inv )
		self.LastInv = inv
		if (self.SlotPanel) then self.SlotPanel:Remove() end
		self.Slots = {}
		local slotPanel = vgui.Create( "DPanel", self )
		function slotPanel:Paint()
		
		end
		local cnt = inv.ItemLimit
		local me = self
		for i=1, cnt do
			local x = ((i > 1) and (i + 0.5)) or i
			local sl = vgui.Create( "DSlot", slotPanel )
			sl:SetSize( slotSize, slotSize )
			sl:SetPos( (x-1)*(slotSize+2), 18 )
			local lbl = vgui.Create( "DShadowedLabel", slotPanel )
			lbl:SetText( ((i == 1) and "Weapon") or tostring( i-1 ) )
			lbl:SizeToContents()
			lbl:SetPos( ((x-0.5)*(slotSize+2))-(lbl:GetWide()*0.5), 0 )
			self.Slots[i] = sl
			if (i == 1) then
				for id, item in pairs( inv.Items ) do
					if (item.Equipped) then
						sl:SetItem( item )
						break
					end
				end
			else
				local item = inv.Items[ i-1 ]
				sl:SetItem( item )
			end
			function sl:DoClick()
				local item = self:GetItem()
				if (!item) then return end
				me:SelectItem( item )
			end
		end
		slotPanel:SetSize( (slotSize + 2) * (cnt + 0.5), slotSize+18 )
		self.SlotPanel = slotPanel
		self:SelectItem( nil )
	end
	
	function DInventory:PerformLayout()
		local sp = self.SlotPanel
		sp:SetPos( 0, self:GetTall() - sp:GetTall() - 5 )
		sp:CenterHorizontal()
		
		local ap = self.ActionPanel
		ap:SetPos( 5, 5 )
		ap:SetSize( self:GetWide()*0.3, self:GetTall() - sp:GetTall() - 15 )
		
		local ip = self.InfoPanel
		ip:SetPos( 10+self:GetWide()*0.3, 5 )
		ip:SetSize( self:GetWide()*0.7 - 15, self:GetTall() - sp:GetTall() - 15 )
	end
	
	local function AddButton( panellist, txt, click )
		local btn = vgui.Create( "DButton" )
		btn:SetText( txt )
		btn.DoClick = click
		panellist:AddItem( btn )
	end
	
	local function AddLabel( panellist, txt )
		local lbl = vgui.Create( "DShadowedLabel" )
		lbl:SetText( txt )
		panellist:AddItem( lbl )
	end
	
	function DInventory:SelectItem( item )
		local ap = self.ActionPanel
		ap:Clear()
		
		for _, sl in pairs( self.Slots ) do
			sl.Selected = (item and (sl:GetItem() == item)) or false
		end
		
		if (!item) then return end
		
		AddLabel( ap, "Select an action:" )
		
		if (item.CanUse) then
			AddButton( ap, "Use", function()
				RunConsoleCommand( "gstore_use", item:Index() )
			end )
		end
		
		if (item.CanEquip) then
			if (!item.Equipped) then
				AddButton( ap, "Equip", function()
					RunConsoleCommand( "gstore_equip", item:Index() )
				end )
			else
				AddButton( ap, "Unequip", function()
					RunConsoleCommand( "gstore_unequip", item:Index() )
				end )
			end
		end
		
		if (item.CanDrop) then
			AddButton( ap, "Drop", function()
				RunConsoleCommand( "gstore_drop", item:Index() )
			end )
		end
		
		AddButton( ap, "Combine", function()
			if (!self.LastInv) then return ErrorNoHalt( "Failed to locate inventory data!\n" ) end
			local firstitem = item
			local menu = DermaMenu()
			for i=1, self.LastInv.ItemLimit do
				local item = self.LastInv.Items[i]
				if (item && (item != firstitem)) then
					local function DoCombine()
						RunConsoleCommand( "gstore_combine", firstitem:Index(), item:Index() )
					end
					menu:AddOption( item.Printname, DoCombine )
				end
			end
			menu:Open()
		end )
	end
	
	function DInventory:Paint()
		
	end
	
	vgui.Register( "DInventory", DInventory, "Panel" )
	
------------------------------------------------------------------------------------------------